#pragma once 
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include "Log.hpp"
#include "Thread.hpp"
#include "Cond.hpp"
#include "Mutex.hpp"
using namespace std;
 namespace ThreadPoolModule
 {
    using namespace ThreadModule;
    using namespace LogModule;
    using namespace CondModule;
    using namespace MutexModule;
    using ThreadModule::Thread;
    using LogModule::Logger;
     static const int gnum=5;
     template<class T>
     class ThreadPool
     {
       public:
       ThreadPool(int num=gnum):_num(num)
       {
         for(int i=0;i<num;i++)
         {
         _threads.emplace_back(
            [this](){
               HandlerTask();
            }
         );
         }
       }
       void Start()
       {
         for(auto & thread:_threads)
         {
            thread.Start();
         }
       }
       void HandlerTask()
       {
         char name[128];
         pthread_getname_np(pthread_self(),name,sizeof(name));
         while(1)
         {
            T t;
            {
               LockGuard lockguard(_mutex);
               while(_taskq.empty())
               {
                  _cond.Wait(_mutex);
               }
               t=_taskq.front();
               _taskq.pop();
            }
            t();
         }
       }
       private:
       vector<Thread>  _threads; 
       int _num;
       queue<T>  _taskq;
       Cond  _cond;
       Mutex  _mutex;
     };
 }